﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.Gateway;
using Wicture.EPC.Service.V1.Models;

namespace Wicture.EPC.Service.V1
{
    public class DbGateway : IDbGateway
    {
        private static Lazy<List<DbRoute>> DbRoutes = new Lazy<List<DbRoute>>(Load);

        private static IConfiguration frameworkConfiguration;

        public DbGateway(IConfiguration configuration)
        {
            frameworkConfiguration = configuration;
        }

        private static List<DbRoute> Load()
        {
            return frameworkConfiguration?.GetSection("DbRoutes").Get<List<DbRoute>>() 
                ?? ConfigurationManager.Settings.GetConfig<List<DbRoute>>("DbRoutes");
        }

        public DatabaseConnection Process(HttpContext context, JToken param, IdentityInfo userInfo)
        {
            var brandCode = param?.Value<string>("brandCode");

            var routes = DbRoutes.Value.Where(r => r.Databases.Any(d => d.Brands.Contains(brandCode)));
            if (routes == null || routes.Count() == 0)
            {
                throw new Exception($"No DbRoute configured for brand: {brandCode}.");
            }

            var readRoute = routes.Any(r => r.ReadOnly) ? routes.First(r => r.ReadOnly) : routes.First();
            var writeRoute = routes.Any(r => !r.ReadOnly) ? routes.First(r => !r.ReadOnly) : routes.First();

            var readOnlyDbName = readRoute.Databases.First(d => d.Brands.Contains(brandCode)).Name;
            var writeableDbName = writeRoute.Databases.First(d => d.Brands.Contains(brandCode)).Name;

            return new DatabaseConnection
            {
                ReadConnectionString = $"server={readRoute.Ip};port={readRoute.Port};user={readRoute.User};" +
                    $"password={readRoute.Password};database={writeableDbName};charset=utf8;convert zero datetime=True;",

                WriteConnectionString = $"server={writeRoute.Ip};port={writeRoute.Port};user={writeRoute.User};" +
                    $"password={writeRoute.Password};database={writeableDbName};charset=utf8;convert zero datetime=True;"
            };
        }
    }
}
